package terra.twl.window;

import terra.Loader;
import terra.model.ItemClientDef;
import terra.network.packet.client.RequestCraftItem;
import terra.slick.GameState;
import terra.twl.widget.ItemSlot;
import de.matthiasmann.twl.Button;
import de.matthiasmann.twl.ThemeInfo;
import de.matthiasmann.twl.Widget;

/**
 *
 * @author Matthias Mann
 */
public class CraftPanel extends Widget implements IDropable{
    
    private int numSlotsX;
    private int numSlotsY;
    private final ItemSlot[] slot;
    private int slotSpacing;

    private ItemSlot dragSlot;
    private ItemSlot dropSlot;
    Button craft, cancel;
    
    public CraftPanel(int numSlotsX, int numSlotsY) {
        this.numSlotsX = numSlotsX;
        this.numSlotsY = numSlotsY;
        this.slot = new ItemSlot[numSlotsX * numSlotsY];

        for(int i=0 ; i<slot.length ; i++) {
            slot[i] = new ItemSlot();
            slot[i].setListener(this);
            add(slot[i]);
        }

        craft = new Button("Craft!");
        craft.setSize(40, 16);
        craft.addCallback(new Craft());
        cancel = new Button("Close");
        cancel.setSize(40, 16);
        cancel.addCallback(new Cancel());
        add(craft);
        add(cancel);
    }
    
    public void update(){
    	for(int i = 0 ; i < slot.length;i++){
    		slot[i].reset();
    	}
    }
    
    public void reset(){
    	for(int i = 0 ; i < slot.length;i++){
    		slot[i].reset();
    	}
    }
    
    @Override
    public int getPreferredInnerWidth() {
        return (slot[0].getPreferredWidth() + slotSpacing)*numSlotsX - slotSpacing;
    }

    @Override
    public int getPreferredInnerHeight() {
        return (slot[0].getPreferredHeight() + slotSpacing)*numSlotsY +craft.getPreferredHeight();
    }

    @Override
    protected void layout() {
        int slotWidth  = slot[0].getPreferredWidth();
        int slotHeight = slot[0].getPreferredHeight();
        
        for(int row=0,y=getInnerY(),i=0 ; row<numSlotsY ; row++) {
            for(int col=0,x=getInnerX() ; col<numSlotsX ; col++,i++) {
                slot[i].adjustSize();
                slot[i].setPosition(x, y);
                x += slotWidth + slotSpacing;
            }
            y += slotHeight + slotSpacing;
        }
        craft.setPosition(getInnerX(), getInnerY()+(slotHeight + slotSpacing)*3);
        cancel.setPosition(getInnerX()+getInnerWidth()-cancel.getWidth(), getInnerY()+(slotHeight + slotSpacing)*3);
    }

    @Override
    protected void applyTheme(ThemeInfo themeInfo) {
        super.applyTheme(themeInfo);
        slotSpacing = themeInfo.getParameter("slotSpacing", 5);
    }
    
    public void dragStarted(ItemSlot slot, int x,int y) {
        if(slot.def != null) {
            dragSlot = slot;
            dragging(slot, x,y);
        }
    }
    
    public void dragging(ItemSlot slot, int x,int y) {
        if(dragSlot != null) {
            Widget w = getWidgetAt(x,y);
            if(w instanceof ItemSlot) {
                setDropSlot((ItemSlot)w);
            } else {
                setDropSlot(null);
            }
        }
    }
    
    boolean containItem(int id){
    	for(int i = 0 ; i < slot.length;i++){
    		if (slot[i].def != null && slot[i].def.getId() == id)
    			return true;
    	}
    	return false;
    }
    
	public ItemSlot getSlotByOId(int ii) {
    	for(int i = 0 ; i < slot.length;i++){
    		if (slot[i].def != null && slot[i].def.getOId() == ii)
    			return slot[i];
    	}
    	return null;
	}
    
    public void dragStopped(ItemSlot slot, int x,int y,Object param,Object param2) {
    	if (param instanceof InventoryPanel){
    		ItemSlot drop = (ItemSlot) GameState.getInstance().getRootPane().getWidgetAt(x,y);
    		if (drop == null)
    			return;
    		if (containItem(slot.def.getId()))
    			return;
    		drop.setDef(new ItemClientDef(slot.def));
    		if (param2 != null)
    			drop.def.setCount((Integer) param2);
    	}
        if(dragSlot != null) {
            dragging(slot, x,y);
            if(dropSlot != null && dropSlot.canDrop() && dropSlot != dragSlot) {
                dropSlot.setDef(dragSlot.def);
                dragSlot.reset();
            }
        }
        setDropSlot(null);
        dragSlot = null;
    	}

    private void setDropSlot(ItemSlot slot) {
        if(slot != dropSlot) {
            if(dropSlot != null) {
                dropSlot.setDropState(false, false);
            }
            dropSlot = slot;
            if(dropSlot != null) {
                dropSlot.setDropState(true, dropSlot == dragSlot || dropSlot.canDrop());
            }
        }
    }
    
    class Cancel implements Runnable{

		@Override
		public void run() {
			reset();
			GameState.getInstance().craftWindow.setVisible(false);
		}
    	
    }
    
    class Craft implements Runnable{

		@Override
		public void run() {
			RequestCraftItem request = new RequestCraftItem(GameState.getInstance().player.getObjectId());
			for(int i = 0; i < RequestCraftItem.COUNT;i++){
				if (i < slot.length){
					if (slot[i].def == null){
						request.itemOids[i] = -1;
						request.itemIds[i] = -1;
						request.itemCounts[i] = -1;
					} else {
					request.itemOids[i] = slot[i].def.getOId();
					request.itemIds[i] = slot[i].def.getId();
					request.itemCounts[i] = slot[i].def.getCount();
					}
				} else {
					request.itemOids[i] = -1;
					request.itemIds[i] = -1;
					request.itemCounts[i] = -1;
				}
			}
			Loader.handler.send(request);
		}
    	
    }


}
